package org.abc.fund.controller.strategy;

import jakarta.validation.Valid;

import java.math.BigDecimal;
import java.util.List;
import org.abc.fund.controller.strategy.response.BacktestResponse;
import org.abc.fund.controller.strategy.response.CombinationStrategyResponse;
import org.abc.fund.controller.strategy.response.StrategyAdjustmentHistoryResponse;
import org.abc.fund.entity.strategy.Backtest;
import org.abc.fund.entity.strategy.CombinationStrategy;
import org.abc.fund.entity.strategy.StrategyAdjustmentHistory;
import org.abc.fund.service.strategy.CombinationStrategyService;
import org.abc.fund.service.strategy.request.backtest.BacktestRequest;
import org.abc.fund.service.strategy.request.create_strategy.CreateStrategyRequest;
import org.abc.fund.service.strategy.request.manual_adjustment.ManualAdjustmentRequest;
import org.abc.fund.service.strategy.request.reject_strategy.RejectStrategyRequest;
import org.abc.fund.util.exception.ResourceNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/strategies")
public class CombinationStrategyController {
  private final CombinationStrategyService strategyService;

  public CombinationStrategyController(CombinationStrategyService CombinationStrategyService) {
    this.strategyService = CombinationStrategyService;
  }

  /**
   * 创建一个新的投资策略
   *
   * @param request 包含策略所有信息的请求体
   * @return 创建的策略对象
   */
  @PostMapping
  public ResponseEntity<CombinationStrategyResponse> createStrategy(
      @Valid @RequestBody CreateStrategyRequest request) {
    CombinationStrategy strategy = strategyService.createStrategy(request);
    return new ResponseEntity<>(
        CombinationStrategyResponse.fromEntity(strategy), HttpStatus.CREATED);
  }

  @PutMapping("/{id}")
  public ResponseEntity<CombinationStrategyResponse> updateStrategy(
      @PathVariable Long id, @Valid @RequestBody CreateStrategyRequest request) {
    CombinationStrategy strategy = strategyService.updateStrategy(id, request);
    return new ResponseEntity<>(CombinationStrategyResponse.fromEntity(strategy), HttpStatus.OK);
  }

  /**
   * 获取所有策略
   *
   * @return 所有策略
   */
  @GetMapping
  public ResponseEntity<List<CombinationStrategyResponse>> getAllStrategies() {
    List<CombinationStrategy> strategies = strategyService.getAllStrategies();
    return new ResponseEntity<>(
        strategies.stream().map(CombinationStrategyResponse::fromEntity).toList(), HttpStatus.OK);
  }

  /**
   * 根据ID获取策略详情
   *
   * @param id 策略ID
   * @return 策略对象或404 Not Found
   */
  @GetMapping("/{id}")
  public ResponseEntity<CombinationStrategyResponse> getStrategyById(@PathVariable Long id) {
    return strategyService
        .getStrategyById(id)
        .map(CombinationStrategyResponse::fromEntity)
        .map(strategy -> new ResponseEntity<>(strategy, HttpStatus.OK))
        .orElseThrow(() -> new ResourceNotFoundException("Strategy not found with id: " + id));
  }

  /**
   * 更新策略状态
   *
   * @param id 策略ID
   * @param newStatus 新的状态
   * @return 更新后的策略对象
   */
  @PutMapping("/{id}/status")
  public ResponseEntity<CombinationStrategyResponse> updateStrategyStatus(
      @PathVariable Long id, @RequestParam CombinationStrategy.Status newStatus) {
    CombinationStrategy updatedStrategy = strategyService.updateStrategyStatus(id, newStatus);
    return new ResponseEntity<>(
        CombinationStrategyResponse.fromEntity(updatedStrategy), HttpStatus.OK);
  }

  /**
   * 为指定策略执行一次回测
   *
   * @param id 策略ID
   * @param request 包含回测起止日期和初始资金的请求体
   * @return 生成的回测记录对象
   */
  @PostMapping("/{id}/backtest")
  public ResponseEntity<BacktestResponse> runBacktest(
      @PathVariable Long id, @Valid @RequestBody BacktestRequest request) {
    Backtest backtest = strategyService.runBacktest(id, request);
    return new ResponseEntity<>(BacktestResponse.fromEntity(backtest), HttpStatus.OK);
  }

  /**
   * 对策略进行手动调仓
   *
   * @param id 策略ID
   * @param request 包含调仓原因和明细的请求体
   * @return 生成的历史调仓记录对象
   */
  @PostMapping("/{id}/adjustments")
  public ResponseEntity<StrategyAdjustmentHistoryResponse> performManualAdjustment(
      @PathVariable Long id, @Valid @RequestBody ManualAdjustmentRequest request) {
    StrategyAdjustmentHistory adjustmentHistory =
        strategyService.performManualAdjustment(id, request);
    return new ResponseEntity<>(
        StrategyAdjustmentHistoryResponse.fromEntity(adjustmentHistory), HttpStatus.CREATED);
  }

  /**
   * 获取一个策略的所有历史调仓记录
   *
   * @param id 策略ID
   * @return 历史调仓记录列表
   */
  @GetMapping("/{id}/adjustments")
  public ResponseEntity<List<StrategyAdjustmentHistoryResponse>> getAdjustmentHistory(
      @PathVariable Long id) {
    List<StrategyAdjustmentHistory> adjustmentHistory = strategyService.getAdjustmentHistory(id);
    return new ResponseEntity<>(
        adjustmentHistory.stream().map(StrategyAdjustmentHistoryResponse::fromEntity).toList(),
        HttpStatus.OK);
  }

  /**
   * 拒绝一个策略 POST /api/strategies/{id}/reject
   *
   * @param id 策略ID
   * @return 更新后的策略
   */
  @PostMapping("/{id}/reject")
  public ResponseEntity<CombinationStrategyResponse> rejectStrategy(
      @PathVariable Long id, @RequestBody RejectStrategyRequest request) {

    CombinationStrategy updatedStrategy = strategyService.rejectStrategy(id, request);

    return new ResponseEntity<>(
        CombinationStrategyResponse.fromEntity(updatedStrategy), HttpStatus.OK);
  }

  /** 提交策略以供审核 POST /api/strategies/{id}/submit */
  @PostMapping("/{id}/submit")
  public ResponseEntity<CombinationStrategyResponse> submitStrategy(@PathVariable Long id) {
    CombinationStrategy updatedStrategy = strategyService.submitForReview(id);
    return new ResponseEntity<>(
        CombinationStrategyResponse.fromEntity(updatedStrategy), HttpStatus.OK);
  }

  /** 批准一个策略 POST /api/strategies/{id}/approve */
  @PostMapping("/{id}/approve")
  public ResponseEntity<CombinationStrategyResponse> approveStrategy(@PathVariable Long id) {
    CombinationStrategy updatedStrategy = strategyService.approveStrategy(id);
    return new ResponseEntity<>(
        CombinationStrategyResponse.fromEntity(updatedStrategy), HttpStatus.OK);
  }

  /** 获取所有待审核的策略 GET /api/strategies/review-queue */
  @GetMapping("/review-queue")
  public ResponseEntity<List<CombinationStrategyResponse>> getReviewQueue() {
    List<CombinationStrategy> strategies = strategyService.getStrategiesForReview();
    List<CombinationStrategyResponse> response =
        strategies.stream().map(CombinationStrategyResponse::fromEntity).toList();
    return ResponseEntity.ok(response);
  }

  /**
   * 获取今日收益
   *
   * @param id 策略ID
   * @return 今日收益
   */
  @GetMapping("/{id}/today-profit")
  public ResponseEntity<BigDecimal> getTodayProfit(@PathVariable Long id) {
    return ResponseEntity.ok(strategyService.getTodayReturn(id));
  }

  /**
   * 获取累计收益
   *
   * @param id 策略ID
   * @return 累计收益
   */
  @GetMapping("/{id}/cumulative-profit")
  public ResponseEntity<BigDecimal> getCumulativeProfit(@PathVariable Long id) {
    return ResponseEntity.ok(strategyService.getCumulativeReturn(id));
  }

  /**
   * 获取一个策略今日的成交额 (换手率)
   *
   * @param id 策略ID
   * @return 今日换手率 (百分比形式)
   */
  @GetMapping("/{id}/today-turnover-rate")
  public ResponseEntity<BigDecimal> getTodayTurnoverRate(@PathVariable Long id) {
    BigDecimal turnoverRate = strategyService.getTodayTurnoverRate(id);
    return ResponseEntity.ok(turnoverRate);
  }
}
